package com.hy.common.config.result;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hy.common.Result.Result;
import com.hy.common.exception.ExceptionResult;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @作用 拦截返回数据，包装成Result类
 * @作者 坏银
 * @时间 2022/4/13 17:15
 */
@RestControllerAdvice
public class ResultResponseHandler implements ResponseBodyAdvice<Object> {
    /**
     * 对进入包装数据的过滤
     *
     * @param methodParameter
     * @param aClass
     * @return
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        //过滤swagger文档
        return !methodParameter.getDeclaringClass().getName().contains("springfox");
    }

    /**
     * 返回数据前拦截包装
     *
     * @param o
     * @param methodParameter
     * @param mediaType
     * @param aClass
     * @param serverHttpRequest
     * @param serverHttpResponse
     * @return
     */
    @Override
    public Object beforeBodyWrite(Object o,
                                  MethodParameter methodParameter,
                                  MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {
        // 对请求的结果在这里统一返回和处理
        if (o instanceof ExceptionResult) {
            // 1、如果返回的结果是一个异常的结果，就把异常返回的结构数据倒腾到R.fail里面即可
            ExceptionResult exceptionResult = (ExceptionResult) o;
            return Result.error(exceptionResult.getCode(), exceptionResult.getMessage());
        } else if (o instanceof String) {
            // 2、因为springmvc数据转换器对String是有特殊处理 StringHttpMessageConverter
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                Result r = Result.success(o);
                return objectMapper.writeValueAsString(r);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return Result.success(o);
    }


}